多筆資料的分頁是網站建置常見的需要,RoR 的分頁真的是異常的簡單,只要透過 will_paginate 的 plugin 或 gem,再加個兩行就完成了。
安裝及使用 will_paginate
在 rails 2.x 版前未納入 gems 中,所以有些教學的資料只說明以 plugin 的方式安裝
# 不建議此法安裝
./script/plugin install svn://errtheblog.com/svn/plugins/will_paginate
然而要能看得懂上述的 svn 的網址,則系統要裝上 subversion 才抓得到安裝;限制是每做一個 project,就要再裝一次,從 gems 安裝就不需如此。
rails 2.x 版發行後,will_paginate就納入到 gems 的官方發佈中,只要執行
gem install will_paginate
然後在該 project 的 config/environment.rb 的最後一行加入 require 'will_paginate' 即可運作。
為了可以較多的資料來操作,此例利用聖經的經文來匯入資料庫之中,首先製作 bible 的scaffold,而下述的欄位中 chap 為第幾章,sec為第幾節,而聖經的書卷可以有中英文或者全名(f)簡稱(s)等欄位;從所要匯入的檔案中,其實會發現,並未達第一正規化;雖然可以把所有的書卷名稱的中英文全簡稱,通通放在另一個 table 上,但會發現反而每叫出一節,就又要再 query 及關聯的名稱出來;然而,所放上去的聖經內容是不會去更動的,所以並不會因未第一正規化而造成不一致的問題,所以就把各書卷的各名稱也寫到同一 table 中:
./script/generate scaffold bible engs:string chap:integer sec:integer txt:text engf:string chinesef:string chineses:string sengs:string
編輯一下:db/migrate/20080922004143_create_bibles.rb ,將 t.timestamps 刪掉,是因為不會更動 table 內容,所以不需要將新增、更新時間的欄位放上去,
class CreateBibles < ActiveRecord::Migration
def self.up
create_table :bibles do |t|
t.string :engs, :limit => 8
t.integer :chap
t.integer :sec
t.text :txt
t.string :engf, :limit => 20
t.string :chinesef, :limit => 32
t.string :chineses, :limit => 10
t.string :sengs, :limit => 4
end
end
def self.down
drop_table :bibles
end
end
檔案內容匯入資料庫
提供下載的檔案原是從 http://bible.fhl.net/public/獲得,但其資料檔是 Big5,又一些格式不符匯入所需,所以將檔案修改格式並轉成UTF-8,請下載 bible.csv.gz 並解開後,執行下列指令就將資料 import 到 bibles 的 table 中。
sqlite3 db/development.sqlite3
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> .import bible.csv bibles
sqlite>
分頁的設定
如果這時候直接 http://SITENAME/bibles 的話,就會造成這三萬多行的資料出現在同一頁,這時只要編輯 app/controllers/bibles_controller.rb 此檔
def index
#@bibles = Bible.find(:all)
@bibles = Bible.paginate :page => params[:page], :per_page => 10
...
再把 app/views/bibles/index.html.erb 這個 view 加上這一行:
<%= will_paginate @records %>
就會自動把每10筆資料分成一頁了。
因為 bibles 這個 table 不需要做增減編修的動作,那就把有關new, update, destroy等actions 及 views 對應相關的區塊及檔案刪除掉,就不會被更動資料了。
頁碼連結的美化
自己常用這個 CSS 做為分頁選擇用
# vi public/stylesheets/page.css 貼上這內容
.pagination {
padding: 3px;
margin: 3px;
}
.pagination a {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #aaaadd;
text-decoration: none;
color: #000099;
}
.pagination a:hover, .pagination a:active {
border: 1px solid #000099;
color: #000;
}
.pagination span.current {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #000099;
font-weight: bold;
background-color: #000099;
color: #FFF;
}
.pagination span.disabled {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #eee;
color: #ddd;
}
再編輯 vi app/views/layouts/bibles.html.erb 加入
<%= stylesheet_link_tag 'page' %>
讓整個 bibles 的 template 可以讀入這新加的 css。
若覺得這pagination太平常太常見,而要不一樣的話,可參考 pagination 的蒐集,將所喜歡的CSS給抄過來用:
Pagination 101:可惜這個連結無效了。
Pagination Gallery
可惜的是will_paginate尚未支援Ajax
不過還是可以Hack..
http://www.google.com.tw/search?q=ajax+will_paginate&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:zh-TW:unofficial&client=firefox-a